package util;

import com.alibaba.fastjson.JSONObject;
import com.google.common.collect.Lists;
import org.apache.commons.lang3.StringUtils;
import org.apache.http.Consts;
import org.apache.http.Header;
import org.apache.http.HttpEntity;
import org.apache.http.client.config.RequestConfig;
import org.apache.http.client.entity.UrlEncodedFormEntity;
import org.apache.http.client.methods.CloseableHttpResponse;
import org.apache.http.client.methods.HttpGet;
import org.apache.http.client.methods.HttpPost;
import org.apache.http.entity.ContentType;
import org.apache.http.entity.StringEntity;
import org.apache.http.impl.client.CloseableHttpClient;
import org.apache.http.impl.client.HttpClientBuilder;
import org.apache.http.impl.client.HttpClients;
import org.apache.http.message.BasicNameValuePair;
import org.apache.http.util.EntityUtils;

import java.io.IOException;
import java.util.List;

/**
 * HTTP工具类，参数统一用JSONObject对象进行传递
 * 需要注意的是，如果参数对顺序有要求，如有签名校验时
 * 在构建JSONObject对象时需要指定ordered = true
 * 创建为LinkedHashMap
 */
@SuppressWarnings("all")
public class HttpClientHelper {
    public static String httpGet(String url) {
        return httpGet(url, null, null);
    }

    public static String httpGet(String url, JSONObject params) {
        return httpGet(url, params, null);
    }

    public static String httpGet(String url, JSONObject params, Header header) {
        String result = "";
        if (StringUtils.isBlank(url)) return result;
        if (params != null && !params.isEmpty()) url = convertGetParams(url, params);
        HttpGet httpGet = new HttpGet(url);
        CloseableHttpClient httpClient = HttpClientBuilder.create().build();
        httpGet.setConfig(getHttpConfig());
        httpGet.setHeader(header);
        try {
            try (CloseableHttpResponse response = httpClient.execute(httpGet)) {
                HttpEntity entity = response.getEntity();
                if (entity != null) {
                    result = EntityUtils.toString(entity, Consts.UTF_8);
                }
            }
        } catch (Exception e) {
            e.printStackTrace();
        } finally {
            // 关闭连接,释放资源
            try {
                httpClient.close();
            } catch (IOException e) {
                e.printStackTrace();
            }
        }
        return result;
    }

    private static String convertGetParams(String url, JSONObject params) {
        StringBuffer sb = url.contains("?") ? new StringBuffer(url) : new StringBuffer(url + "?");
        params.forEach((k, v) -> sb.append(k).append("=").append(v).append("&"));
        return sb.substring(0, sb.length() - 1);
    }

    public static String httpPost(String url, JSONObject params) {
        return httpPost(url, params, null, ContentType.APPLICATION_JSON);
    }

    public static String httpPost(String url, JSONObject params, Header header) {
        return httpPost(url, params, header, ContentType.APPLICATION_JSON);
    }

    public static String httpPost(String url, JSONObject params, Header header, ContentType contentType) {
        String result = "";
        if (StringUtils.isBlank(url)) return result;
        //创建默认的httpClient实例
        CloseableHttpClient httpClient = HttpClients.createDefault();
        //创建httpPost
        HttpPost httpPost = new HttpPost(url);
        httpPost.addHeader(header);
        httpPost.setConfig(getHttpConfig());
        StringEntity request;
        try {
            if (ContentType.APPLICATION_FORM_URLENCODED == contentType) {
                List<BasicNameValuePair> pairs = Lists.newArrayList();
                params.forEach((key, value) -> pairs.add(new BasicNameValuePair(key, String.valueOf(value))));
                request = new UrlEncodedFormEntity(pairs, Consts.UTF_8);
            } else {
                request = new StringEntity(String.valueOf(params), ContentType.APPLICATION_JSON);
            }
            httpPost.setEntity(request);
            try (CloseableHttpResponse response = httpClient.execute(httpPost)) {
                HttpEntity entity = response.getEntity();
                if (entity != null) {
                    result = EntityUtils.toString(entity, Consts.UTF_8);
                }
            }
        } catch (Exception e) {
            e.printStackTrace();
        } finally {
            //关闭连接,释放资源
            try {
                httpClient.close();
            } catch (IOException e) {
                e.printStackTrace();
            }
        }
        return result;
    }

    private static RequestConfig getHttpConfig() {
        return RequestConfig.custom()
                .setConnectTimeout(10000)//一、连接超时：connectionTimeout-->指的是连接一个url的连接等待时间
                .setSocketTimeout(10000)// 二、读取数据超时：SocketTimeout-->指的是连接上一个url，获取response的返回等待时间
                .setConnectionRequestTimeout(10000)
                .build();
    }
}
